package com.gyy.Thermometry;

import com.gyy.sdk.HCNetSDK;
import com.sun.jna.Pointer;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 实时测温：包括普通模式和专家模式
 * 包括普通模式：获取全屏的最低最高平均温度
 * 专家模式：获取每个规则各自的最低最高平均温度
 *
 * @Author sdk支持
 * @Date 2021/3/15 17:54
 */
public class RealTimeThermometry {
    static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
    public FileOutputStream thermometryupload = null;
    public static FRemoteConfigCallback fRemoteConfigCallback;

    /**
     * 获取实时测温的温度数据
     *
     * @param lUserID     用户登录句柄
     * @param iChannelNum 通道号，从1开始，0xffffffff代表获取全部通道
     * @param RuleID      规则ID，0代表获取全部规则，具体规则ID从1开始
     * @param Mode        长连接模式：0-保留；1-定时模式；2-温差模式
     * @param Interval    上传间隔（仅温差模式支持），取值范围：1-3600 秒，填0则默认3600S上传一次
     */
    public void getThermometryData(int lUserID, int iChannelNum, byte RuleID, byte Mode, short Interval) {

        long lHandle;
        HCNetSDK.NET_DVR_REALTIME_THERMOMETRY_COND m_strRealtimeThermometryCond = new HCNetSDK.NET_DVR_REALTIME_THERMOMETRY_COND();
        m_strRealtimeThermometryCond.dwSize = m_strRealtimeThermometryCond.size();
        m_strRealtimeThermometryCond.dwChan = iChannelNum;
        m_strRealtimeThermometryCond.byRuleID = RuleID;//规则ID，0代表获取全部规则，具体规则ID从1开始
        m_strRealtimeThermometryCond.byMode = Mode;//长连接模式：0-保留；1-定时模式；2-温差模式
        m_strRealtimeThermometryCond.wInterval = Interval;//上传间隔（仅温差模式支持），取值范围：1-3600 秒，填0则默认3600S上传一次

        fRemoteConfigCallback = new FRemoteConfigCallback();
        Pointer pUserData = null;
        m_strRealtimeThermometryCond.write();

        lHandle = hCNetSDK.NET_DVR_StartRemoteConfig(lUserID, HCNetSDK.NET_DVR_GET_REALTIME_THERMOMETRY, m_strRealtimeThermometryCond.getPointer(), m_strRealtimeThermometryCond.dwSize, fRemoteConfigCallback, pUserData);
        if (lHandle < 0) {
            System.out.println("建立实时测温规则获取长连接失败，错误号：" + hCNetSDK.NET_DVR_GetLastError());
            return;
        }
        System.out.println("建立实时测温规则获取长连接成功!");
        try {
            // 只要程序没结束，实时温度数据就会一直上传
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /******************************************************************************
     * 内部类:   FRemoteConfigCallback
     * 状态回调函数
     ******************************************************************************/
    public class FRemoteConfigCallback implements HCNetSDK.FRemoteConfigCallBack {
        //状态回调函数
        public void invoke(int dwType, Pointer lpBuffer, int dwBufferLen, Pointer pUserData) {
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String newName = sf.format(new Date());
            System.out.println("长连接回调获取数据类型:" + dwType);
            switch (dwType) {
                case 0://NET_SDK_CALLBACK_TYPE_STATUS
                    HCNetSDK.REMOTECONFIGSTATUS_THERMOMETRY struCfgStatus = new HCNetSDK.REMOTECONFIGSTATUS_THERMOMETRY();
                    struCfgStatus.write();
                    Pointer pCfgStatus = struCfgStatus.getPointer();
                    pCfgStatus.write(0, lpBuffer.getByteArray(0, struCfgStatus.size()), 0, struCfgStatus.size());
                    struCfgStatus.read();
                    int iStatus = 0;
                    for (int i = 0; i < 4; i++) {
                        int ioffset = i * 8;
                        int iByte = struCfgStatus.byStatus[i] & 0xff;
                        iStatus = iStatus + (iByte << ioffset);
                    }

                    switch (iStatus) {
                        case 1000:// NET_SDK_CALLBACK_STATUS_SUCCESS
                            System.out.println("手动测温实时获取成功,dwStatus:" + iStatus);
                            try {
                                thermometryupload.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            break;
                        case 1001:
                            System.out.println("正在实时获取手动测温,dwStatus:" + iStatus);
                            break;
                        case 1002:
                            int iErrorCode = 0;
                            for (int i = struCfgStatus.size() - 3; i <= struCfgStatus.size(); i++) {
                                int ioffset = i * 8;
                                int iByte = struCfgStatus.byErrorCode[i] & 0xff;
                                iErrorCode = iErrorCode + (iByte << ioffset);
                            }
                            System.out.println("手动测温实时获取失败, dwStatus:" + iStatus + "错误号:" + iErrorCode);
                            break;
                    }
                    break;
                case 2://NET_SDK_CALLBACK_TYPE_DATA
                    HCNetSDK.NET_DVR_THERMOMETRY_UPLOAD m_struThermometryUpload = new HCNetSDK.NET_DVR_THERMOMETRY_UPLOAD();
                    m_struThermometryUpload.write();
                    Pointer pmt = m_struThermometryUpload.getPointer();
                    pmt.write(0, lpBuffer.getByteArray(0, m_struThermometryUpload.size()), 0, m_struThermometryUpload.size());
                    m_struThermometryUpload.read();

                    try {
                        if (thermometryupload == null) {
                            thermometryupload = new FileOutputStream(".\\pic\\thermometryUpload.txt");
                        }

                        byte[] byte1;
                        String strTemp = "";
                        if (m_struThermometryUpload.byRuleCalibType == 0) {   //规则标定类型：0- 点
                            strTemp = "规则ID：" + m_struThermometryUpload.byRuleID
                                    + "，规则名称：" + new String(m_struThermometryUpload.szRuleName, "GBK").trim()
                                    + "，规则类型：" + m_struThermometryUpload.byRuleCalibType
                                    + "，预置点号：" + m_struThermometryUpload.wPresetNo
                                    + "，点温度：" + m_struThermometryUpload.struPointThermCfg.fTemperature
                                    + "，点坐标：(" + m_struThermometryUpload.struPointThermCfg.struPoint.fX + "," + m_struThermometryUpload.struPointThermCfg.struPoint.fY + ")"
                                    + "\n";
                        } else if (m_struThermometryUpload.byRuleCalibType == 1) {   //规则标定类型：1- 框
                            strTemp = "规则ID：" + m_struThermometryUpload.byRuleID
                                    + "，规则名称：" + new String(m_struThermometryUpload.szRuleName, "GBK").trim()
                                    + "，规则类型：" + m_struThermometryUpload.byRuleCalibType
                                    + "，预置点号：" + m_struThermometryUpload.wPresetNo
                                    + "，区域最高温度：" + m_struThermometryUpload.struLinePolygonThermCfg.fMaxTemperature
                                    + "，区域最低温度：" + m_struThermometryUpload.struLinePolygonThermCfg.fMinTemperature
                                    + "，区域平均温度：" + m_struThermometryUpload.struLinePolygonThermCfg.fAverageTemperature
                                    + "，区域温差：" + m_struThermometryUpload.struLinePolygonThermCfg.fTemperatureDiff
                                    + "，有效点数：" + m_struThermometryUpload.struLinePolygonThermCfg.struRegion.dwPointNum
                                    + "，区域边界点坐标：";
                            String temp = "";
                            for (int ij = 0; ij < m_struThermometryUpload.struLinePolygonThermCfg.struRegion.dwPointNum; ij++) {
                                temp = temp + ij + "-(" + m_struThermometryUpload.struLinePolygonThermCfg.struRegion.struPos[ij].fX + "," + m_struThermometryUpload.struLinePolygonThermCfg.struRegion.struPos[ij].fY + ")、";
                            }
                            strTemp = strTemp + temp + "\n";
                        } else if (m_struThermometryUpload.byRuleCalibType == 2) {   //规则标定类型：2- 线
                            strTemp = "规则ID：" + m_struThermometryUpload.byRuleID
                                    + "，规则名称：" + new String(m_struThermometryUpload.szRuleName, "GBK").trim()
                                    + "，规则类型：" + m_struThermometryUpload.byRuleCalibType
                                    + "，预置点号：" + m_struThermometryUpload.wPresetNo
                                    + "，线最高温度：" + m_struThermometryUpload.struLinePolygonThermCfg.fMaxTemperature
                                    + "，线最低温度：" + m_struThermometryUpload.struLinePolygonThermCfg.fMinTemperature
                                    + "，线平均温度：" + m_struThermometryUpload.struLinePolygonThermCfg.fAverageTemperature
                                    + "，线温差：" + m_struThermometryUpload.struLinePolygonThermCfg.fTemperatureDiff
                                    + "，有效点数：" + m_struThermometryUpload.struLinePolygonThermCfg.struRegion.dwPointNum
                                    + "，线端点坐标：0-(" + m_struThermometryUpload.struLinePolygonThermCfg.struRegion.struPos[0].fX + "," + m_struThermometryUpload.struLinePolygonThermCfg.struRegion.struPos[0].fY + ")"
                                    + "、1-(" + m_struThermometryUpload.struLinePolygonThermCfg.struRegion.struPos[1].fX + "," + m_struThermometryUpload.struLinePolygonThermCfg.struRegion.struPos[1].fY + ")"
                                    + "\n";
                        }
                        byte1 = (newName + " : " + strTemp).getBytes();
                        thermometryupload.write(byte1);

                    } catch (FileNotFoundException e) {
                        System.out.println("路径不存在");
                    } catch (IOException e) {
                        System.out.println("异常");
                    }

            }
        }

    }


}
